package com.sxpi.zixun.controller.login;

import com.sxpi.zixun.bo.PugUserBo;
import com.sxpi.zixun.common.enums.AdminUserResultEnum;
import com.sxpi.zixun.common.utils.fn.asserts.Vsserts;
import com.sxpi.zixun.common.utils.pwd.DesUtils;
import com.sxpi.zixun.common.utils.pwd.MD5Util;
import com.sxpi.zixun.service.jwt.JwtService;
import com.sxpi.zixun.config.redis.AdminRedisKeyManager;
import com.sxpi.zixun.config.redis.IJwtBlackService;
import com.sxpi.zixun.controller.BaseController;
import com.sxpi.zixun.pojo.AdminUser;
import com.sxpi.zixun.service.adminuser.IAdminUserService;
import com.sxpi.zixun.vo.LoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * @author 蓝欣
 */
@RestController
@Slf4j
public class PassportLoginController extends BaseController implements AdminRedisKeyManager {

    @Autowired
    private IAdminUserService iAdminUserService;

    @Autowired
    private JwtService jwtService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    @Qualifier(value = "jwtBlackStringService")
    private IJwtBlackService iJwtBlackService;

    /**
     * 根据用户的名称查询用户信息
     * 用户每次登录的时候都会刷新用户id
     * @param loginUserVo
     * @return
     */
    @PostMapping("/login/toLogin")
    public PugUserBo markOrder(@RequestBody LoginVo loginUserVo){
        Vsserts.isEmptyEx(loginUserVo.getUsername(),AdminUserResultEnum.USER_NAME_NOT_EMPTY);
        Vsserts.isEmptyEx(loginUserVo.getPassword(),AdminUserResultEnum.USER_PWD_EMPTY);
        Vsserts.isEmptyEx(loginUserVo.getCode(),AdminUserResultEnum.USER_CODE_NOT_EMPTY);
        // 根据uuid获取redis缓存中的信息
        String redisCode = redisTemplate.opsForValue().get(loginUserVo.getCodeUuid());
        Vsserts.isEmptyEx(redisCode,AdminUserResultEnum.USER_CODE_PAST_DUE);
        // 判断验证码是否正确
        Vsserts.isFalseEx(redisCode.equalsIgnoreCase(loginUserVo.getCode()),AdminUserResultEnum.USER_CODE_INPUT_ERROR);
        // 用户解密
        loginUserVo.setUsername(DesUtils.decrypt(loginUserVo.getUsername()));
        AdminUser dbLoginUser = iAdminUserService.login(loginUserVo);
        Vsserts.isNullEx(dbLoginUser,AdminUserResultEnum.USER_NULL_ERROR);
        // 用户输入的密码解密
        String inputPwd = DesUtils.decrypt(loginUserVo.getPassword());
        String inputMd5Pwd = MD5Util.md5slat(inputPwd);
        boolean isLogin = dbLoginUser.getPassword().equalsIgnoreCase(inputMd5Pwd);
        Vsserts.isNotTrueEx(isLogin,AdminUserResultEnum.USER_INPUT_PASSWORD_ERROR);
        // 根据登录的用户生成token
        PugUserBo userBo = new PugUserBo();
        String token = jwtService.createToken(dbLoginUser.getId());
        userBo.setToken(token);
        // 这里把敏感信息全部清空然后返回，后面在优化，简单跑起来
        dbLoginUser.setPassword(null);
        userBo.setUser(dbLoginUser);
        // 查询角色
        userBo.setRoleNames(iAdminUserService.getRoleNames(dbLoginUser.getId()));
        // 权限
        userBo.setPermissions(iAdminUserService.findByUserPermission(dbLoginUser.getId()));
        // 登录挤下线
        String tokenUuid = UUID.randomUUID().toString();
        String tokenUuidKey = USER_LOGOUT_TOKEN_KEY + dbLoginUser.getId();
        redisTemplate.opsForValue().set(tokenUuidKey,tokenUuid);
        userBo.setTokenUuid(tokenUuid);

        // jwt 和 redis的续期
        jwtService.redisToken(token);
        return userBo;
    }

    /**
     * 删除下线的uuid
     * 通过请求头获取
     * @param request
     * @return
     */
    @PostMapping("/login/logout")
    public String logout(HttpServletRequest request){
        String token = jwtService.getToken(request);
        String userId = jwtService.getTokenUserId(request);
        Vsserts.isEmptyEx(token,AdminUserResultEnum.TOKEN_NOT_FOUND);
        Vsserts.isEmptyEx(userId,AdminUserResultEnum.USER_NAME_NOT_EMPTY);
        String tokenUuidKey = USER_LOGOUT_TOKEN_KEY + userId;
        redisTemplate.delete(tokenUuidKey);
        // 删除续期的redis的key
        String tokenKey = USER_LOGIN_TOKEN_KEY + token;
        redisTemplate.delete(tokenKey);
        // 黑白名单
        iJwtBlackService.addBlackList(token);
        return "success";
    }
}
